package com.property.demo.controller;

import com.property.demo.dto.ApiResponse;
import com.property.demo.model.Role;
import com.property.demo.model.RolePermission;
import com.property.demo.repository.RolePermissionRepository;
import com.property.demo.repository.RoleRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.transaction.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/roles")
public class RoleController {
    
    private static final Logger logger = LoggerFactory.getLogger(RoleController.class);
    
    @Autowired
    private RoleRepository roleRepository;
    
    @Autowired
    private RolePermissionRepository rolePermissionRepository;
    
    @GetMapping
    public ResponseEntity<?> getAllRoles() {
        logger.info("获取所有角色");
        
        try {
            List<Role> roles = roleRepository.findAll();
            logger.info("成功获取所有角色 - 数量: {}", roles.size());
            return ResponseEntity.ok(roles);
        } catch (Exception e) {
            logger.error("获取所有角色失败: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "获取所有角色失败: " + e.getMessage()));
        }
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<?> getRoleById(@PathVariable Long id) {
        logger.info("获取角色详情 - ID: {}", id);
        
        try {
            Optional<Role> roleOpt = roleRepository.findById(id);
            
            if (!roleOpt.isPresent()) {
                logger.warn("未找到角色 - ID: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            Role role = roleOpt.get();
            logger.info("成功获取角色详情 - ID: {}, 名称: {}", id, role.getName());
            return ResponseEntity.ok(role);
        } catch (Exception e) {
            logger.error("获取角色详情失败 - ID: {}, 错误: {}", id, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "获取角色详情失败: " + e.getMessage()));
        }
    }
    
    @PostMapping
    public ResponseEntity<?> createRole(@RequestBody Role role) {
        logger.info("创建角色 - 名称: {}, 编码: {}", role.getName(), role.getCode());
        
        try {
            if (roleRepository.existsByCode(role.getCode())) {
                logger.warn("创建角色失败 - 角色编码已存在: {}", role.getCode());
                return ResponseEntity.badRequest().body(new ApiResponse(false, "角色编码已被使用!"));
            }

            Role savedRole = roleRepository.save(role);
            
            logger.info("角色创建成功 - ID: {}, 名称: {}", savedRole.getId(), savedRole.getName());
            return ResponseEntity.ok(savedRole);
        } catch (Exception e) {
            logger.error("创建角色失败 - 名称: {}, 错误: {}", role.getName(), e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "创建角色失败: " + e.getMessage()));
        }
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<?> updateRole(@PathVariable Long id, @RequestBody Role roleDetails) {
        logger.info("更新角色 - ID: {}", id);
        
        try {
            Optional<Role> roleOpt = roleRepository.findById(id);
            
            if (!roleOpt.isPresent()) {
                logger.warn("更新角色失败 - 未找到角色 ID: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            Role role = roleOpt.get();
            
            // 不允许修改ROLE_ADMIN的编码
            if ("ROLE_ADMIN".equals(role.getCode()) && !roleDetails.getCode().equals(role.getCode())) {
                logger.warn("更新角色失败 - 不允许修改管理员角色编码");
                return ResponseEntity.badRequest().body(new ApiResponse(false, "不允许修改管理员角色编码!"));
            }
            
            // 检查角色编码是否已被其他角色使用
            if (!role.getCode().equals(roleDetails.getCode()) && 
                roleRepository.existsByCode(roleDetails.getCode())) {
                logger.warn("更新角色失败 - 角色编码已被使用: {}", roleDetails.getCode());
                return ResponseEntity.badRequest().body(new ApiResponse(false, "角色编码已被使用!"));
            }
            
            // 更新角色信息
            role.setName(roleDetails.getName());
            role.setDescription(roleDetails.getDescription());
            // 只有在非ROLE_ADMIN的情况下才更新编码
            if (!"ROLE_ADMIN".equals(role.getCode())) {
                role.setCode(roleDetails.getCode());
            }
            
            Role updatedRole = roleRepository.save(role);
            
            logger.info("角色更新成功 - ID: {}, 名称: {}", updatedRole.getId(), updatedRole.getName());
            return ResponseEntity.ok(updatedRole);
        } catch (Exception e) {
            logger.error("更新角色失败 - ID: {}, 错误: {}", id, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "更新角色失败: " + e.getMessage()));
        }
    }
    
    @DeleteMapping("/{id}")
    @Transactional
    public ResponseEntity<?> deleteRole(@PathVariable Long id) {
        logger.info("删除角色 - ID: {}", id);
        
        try {
            Optional<Role> roleOpt = roleRepository.findById(id);
            
            if (!roleOpt.isPresent()) {
                logger.warn("删除角色失败 - 未找到角色 ID: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            Role role = roleOpt.get();
            
            // 不允许删除ROLE_ADMIN角色
            if ("ROLE_ADMIN".equals(role.getCode())) {
                logger.warn("删除角色失败 - 不允许删除管理员角色");
                return ResponseEntity.badRequest().body(new ApiResponse(false, "不允许删除管理员角色!"));
            }
            
            // 删除角色权限关联
            rolePermissionRepository.deleteByRoleId(id);
            
            // 删除角色
            roleRepository.delete(role);
            
            logger.info("角色删除成功 - ID: {}, 名称: {}", id, role.getName());
            return ResponseEntity.ok(new ApiResponse(true, "角色删除成功!"));
        } catch (Exception e) {
            logger.error("删除角色失败 - ID: {}, 错误: {}", id, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "删除角色失败: " + e.getMessage()));
        }
    }
    
    @PostMapping("/{roleId}/permissions")
    @Transactional
    public ResponseEntity<?> assignPermissionsToRole(@PathVariable Long roleId, @RequestBody Map<String, List<Long>> request) {
        logger.info("为角色分配权限 - 角色ID: {}", roleId);
        
        try {
            Optional<Role> roleOpt = roleRepository.findById(roleId);
            
            if (!roleOpt.isPresent()) {
                logger.warn("分配权限失败 - 未找到角色 ID: {}", roleId);
                return ResponseEntity.notFound().build();
            }
            
            List<Long> permissionIds = request.get("permissionIds");
            if (permissionIds == null) {
                logger.warn("分配权限失败 - 未提供权限ID列表");
                return ResponseEntity.badRequest().body(new ApiResponse(false, "未提供权限ID列表!"));
            }
            
            // 先删除该角色的所有权限
            rolePermissionRepository.deleteByRoleId(roleId);
            
            // 添加新的权限
            List<RolePermission> rolePermissions = permissionIds.stream()
                .map(permissionId -> {
                    RolePermission rolePermission = new RolePermission();
                    rolePermission.setRoleId(roleId);
                    rolePermission.setPermissionId(permissionId);
                    return rolePermission;
                })
                .collect(Collectors.toList());
            
            rolePermissionRepository.saveAll(rolePermissions);
            
            logger.info("为角色分配权限成功 - 角色ID: {}, 权限数量: {}", roleId, permissionIds.size());
            
            Map<String, Object> response = new HashMap<>();
            response.put("roleId", roleId);
            response.put("permissionIds", permissionIds);
            response.put("message", "权限分配成功");
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("为角色分配权限失败 - 角色ID: {}, 错误: {}", roleId, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "分配权限失败: " + e.getMessage()));
        }
    }
    
    @GetMapping("/{roleId}/permissions")
    public ResponseEntity<?> getRolePermissions(@PathVariable Long roleId) {
        logger.info("获取角色权限 - 角色ID: {}", roleId);
        
        try {
            Optional<Role> roleOpt = roleRepository.findById(roleId);
            
            if (!roleOpt.isPresent()) {
                logger.warn("获取角色权限失败 - 未找到角色 ID: {}", roleId);
                return ResponseEntity.notFound().build();
            }
            
            List<RolePermission> rolePermissions = rolePermissionRepository.findByRoleId(roleId);
            List<Long> permissionIds = rolePermissions.stream()
                .map(RolePermission::getPermissionId)
                .collect(Collectors.toList());
            
            logger.info("获取角色权限成功 - 角色ID: {}, 权限数量: {}", roleId, permissionIds.size());
            
            Map<String, Object> response = new HashMap<>();
            response.put("roleId", roleId);
            response.put("permissionIds", permissionIds);
            
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            logger.error("获取角色权限失败 - 角色ID: {}, 错误: {}", roleId, e.getMessage(), e);
            return ResponseEntity.badRequest().body(new ApiResponse(false, "获取角色权限失败: " + e.getMessage()));
        }
    }
} 